import React, { useState } from "react"
import { makeAutoObservable } from "mobx"
import { observer } from "mobx-react-lite"

// 定义Todo类型
interface Todo {
  id: number
  text: string
  completed: boolean
}

// 创建MobX Store类
class TodoStore {
  todos: Todo[] = [
    { id: 1, text: "学习 MobX", completed: false },
    { id: 2, text: "理解 Observable 状态", completed: false },
  ]

  constructor() {
    // 使所有属性和方法可观察
    makeAutoObservable(this)
  }

  // 添加todo
  addTodo(text: string) {
    this.todos.push({
      id: Date.now(),
      text,
      completed: false,
    })
  }

  // 切换completed状态
  toggleTodo(id: number) {
    const todo = this.todos.find((todo) => todo.id === id)
    if (todo) {
      todo.completed = !todo.completed
    }
  }

  // 删除todo
  deleteTodo(id: number) {
    this.todos = this.todos.filter((todo) => todo.id !== id)
  }

  // 计算属性: 获取完成的todo数量
  get completedCount() {
    return this.todos.filter((todo) => todo.completed).length
  }

  // 计算属性: 获取未完成的todo数量
  get remainingCount() {
    return this.todos.length - this.completedCount
  }
}

// 创建store实例
const todoStore = new TodoStore()

// TodoList组件 - 使用observer包装以响应观察到的变化
const TodoList = observer(() => {
  return (
    <ul className="todo-list">
      {todoStore.todos.map((todo) => (
        <li key={todo.id} className={todo.completed ? "completed" : ""}>
          <span onClick={() => todoStore.toggleTodo(todo.id)}>{todo.text}</span>
          <button onClick={() => todoStore.deleteTodo(todo.id)}>删除</button>
        </li>
      ))}
    </ul>
  )
})

// Todo统计组件 - 使用observer包装
const TodoStats = observer(() => {
  return (
    <div className="todo-stats">
      <span>完成: {todoStore.completedCount}</span>
      <span>剩余: {todoStore.remainingCount}</span>
    </div>
  )
})

// AddTodo组件
const AddTodo = observer(() => {
  const [text, setText] = useState("")
  // 在组件内部使用todoStore
  const store = todoStore

  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault()
    if (text.trim()) {
      store.addTodo(text)
      setText("")
    }
  }

  return (
    <form onSubmit={handleSubmit}>
      <input
        type="text"
        value={text}
        onChange={(e) => setText(e.target.value)}
        placeholder="添加新任务..."
      />
      <button type="submit">添加</button>
    </form>
  )
})

// 主组件
const MobxExample: React.FC = () => {
  return (
    <div className="state-example">
      <h2>MobX 实现</h2>
      <p>此方案使用 MobX 响应式状态管理库</p>

      <div className="todo-container">
        <AddTodo />
        <TodoStats />
        <TodoList />
      </div>

      <div className="explanation">
        <h3>核心概念:</h3>
        <ul>
          <li>
            <strong>Observable</strong>:
            可被观察的状态，当其变化时会触发相关重新计算
          </li>
          <li>
            <strong>Action</strong>: 修改状态的方法
          </li>
          <li>
            <strong>Computed</strong>:
            基于现有状态派生出的值，自动缓存并在依赖变化时更新
          </li>
          <li>
            <strong>Reaction</strong>: 响应可观察状态变化的副作用
          </li>
          <li>
            <strong>Observer</strong>: 将 React 组件与 MobX
            可观察状态连接的高阶组件
          </li>
        </ul>

        <h3>面试考点:</h3>
        <ul>
          <li>
            MobX 与 Redux 的异同及适用场景（MobX 更灵活，允许直接修改状态；Redux
            强制不可变数据流）
          </li>
          <li>MobX 的工作原理（基于代理和拦截器实现细粒度的响应式更新）</li>
          <li>MobX 中的性能优化（如何避免不必要的重新渲染）</li>
          <li>MobX 的副作用管理（autorun、reaction 和 when）</li>
          <li>MobX 中如何处理异步操作</li>
          <li>严格模式（只在动作内修改状态）的重要性</li>
        </ul>
      </div>
    </div>
  )
}

export default MobxExample
